// +----------------------------------------------------------------------
// | ShopSuite商城系统 [ 赋能开发者，助力企业发展 ]
// +----------------------------------------------------------------------
// | 版权所有 随商信息技术（上海）有限公司
// +----------------------------------------------------------------------
// | 未获商业授权前，不得将本软件用于商业用途。禁止整体或任何部分基础上以发展任何派生版本、
// | 修改版本或第三方版本用于重新分发。
// +----------------------------------------------------------------------
// | 官方网站: https://www.shopsuite.cn  https://www.modulithshop.cn
// +----------------------------------------------------------------------
// | 版权和免责声明:
// | 本公司对该软件产品拥有知识产权（包括但不限于商标权、专利权、著作权、商业秘密等）
// | 均受到相关法律法规的保护，任何个人、组织和单位不得在未经本团队书面授权的情况下对所授权
// | 软件框架产品本身申请相关的知识产权，禁止用于任何违法、侵害他人合法权益等恶意的行为，禁
// | 止用于任何违反我国法律法规的一切项目研发，任何个人、组织和单位用于项目研发而产生的任何
// | 意外、疏忽、合约毁坏、诽谤、版权或知识产权侵犯及其造成的损失 (包括但不限于直接、间接、
// | 附带或衍生的损失等)，本团队不承担任何法律责任，本软件框架只能用于公司和个人内部的
// | 法律所允许的合法合规的软件产品研发，详细见https://www.modulithshop.cn/policy
// +----------------------------------------------------------------------
package com.suisung.shopsuite.trade.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.suisung.shopsuite.account.model.entity.UserDistribution;
import com.suisung.shopsuite.account.model.entity.UserInfo;
import com.suisung.shopsuite.account.model.entity.UserLevel;
import com.suisung.shopsuite.account.repository.UserDistributionRepository;
import com.suisung.shopsuite.account.repository.UserInfoRepository;
import com.suisung.shopsuite.account.service.UserLevelService;
import com.suisung.shopsuite.common.utils.CheckUtil;
import com.suisung.shopsuite.common.utils.CommonUtil;
import com.suisung.shopsuite.common.utils.TimeRange;
import com.suisung.shopsuite.common.utils.TimeUtil;
import com.suisung.shopsuite.core.web.service.impl.BaseServiceImpl;
import com.suisung.shopsuite.pay.model.entity.DistributionCommission;
import com.suisung.shopsuite.pay.repository.DistributionCommissionRepository;
import com.suisung.shopsuite.sys.service.ConfigBaseService;
import com.suisung.shopsuite.trade.dao.DistributionOrderDao;
import com.suisung.shopsuite.trade.model.entity.*;
import com.suisung.shopsuite.trade.model.req.DistributionOrderListReq;
import com.suisung.shopsuite.trade.model.res.DistributionOrderRes;
import com.suisung.shopsuite.trade.model.vo.DistributionOrderVo;
import com.suisung.shopsuite.trade.repository.DistributionGeneratedCommissionRepository;
import com.suisung.shopsuite.trade.repository.DistributionOrderItemRepository;
import com.suisung.shopsuite.trade.repository.DistributionOrderRepository;
import com.suisung.shopsuite.trade.repository.OrderInfoRepository;
import com.suisung.shopsuite.trade.service.DistributionOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 推广订单收益详情表 服务实现类
 * </p>
 *
 * @author Xinze
 * @since 2021-09-11
 */
@Service
public class DistributionOrderServiceImpl extends BaseServiceImpl<DistributionOrderRepository, DistributionOrder, DistributionOrderListReq> implements DistributionOrderService {

    @Autowired
    private UserInfoRepository userInfoRepository;

    @Autowired
    private UserLevelService userLevelService;

    @Autowired
    private DistributionOrderDao distributionOrderDao;

    @Autowired
    private ConfigBaseService configBaseService;

    @Autowired
    private UserDistributionRepository userDistributionRepository;

    @Autowired
    private DistributionOrderItemRepository distributionOrderItemRepository;

    @Autowired
    private DistributionGeneratedCommissionRepository distributionGeneratedCommissionRepository;

    @Autowired
    private DistributionCommissionRepository distributionCommissionRepository;

    @Autowired
    private OrderInfoRepository orderInfoRepository;

    @Override
    public DistributionOrderRes listsOrder(DistributionOrderListReq distributionOrderListReq) {
        DistributionOrderRes distributionOrderRes = new DistributionOrderRes();
        Integer timeFlag = distributionOrderListReq.getTimeFlag();
        QueryWrapper<DistributionOrder> queryWrapper = new QueryWrapper<>();

        TimeRange timeRange = null;

        if (timeFlag == 1) {
            timeRange = TimeUtil.today();
        } else if (timeFlag == 2) {
            timeRange = TimeUtil.month();
        } else if (timeFlag == 3) {
            timeRange = TimeUtil.lastNMonths(3);
        }

        Long startTime = null;
        Long endTime = null;

        if (timeRange != null) {
            queryWrapper.between("uo_time", timeRange.getStart(), timeRange.getEnd());

            startTime = timeRange.getStart();
            endTime = timeRange.getEnd();
        }


        Integer uoLevel = distributionOrderListReq.getUoLevel();

        if (uoLevel != null && uoLevel != 0) {
            if (uoLevel == 1) {
                queryWrapper.in("uo_level", ListUtil.toList(1, 2, 3, 11, 12, 13));
            } else if (uoLevel == 81) {
                queryWrapper.in("uo_level", ListUtil.toList(14, 15, 16, 4, 5, 6));
            } else {
                queryWrapper.eq("uo_level", uoLevel);
            }
        }
        Integer userId = distributionOrderListReq.getUserId();
        queryWrapper.eq("user_id", userId).eq("uo_is_paid", true);
        IPage<DistributionOrder> distributionOrderPage = lists(queryWrapper, distributionOrderListReq.getPage(), distributionOrderListReq.getSize());
        distributionOrderRes.setUoBuyCommissionTotal(BigDecimal.ZERO);
        if (distributionOrderPage != null && CollectionUtil.isNotEmpty(distributionOrderPage.getRecords())) {
            List<DistributionOrder> distributionOrders = distributionOrderPage.getRecords();
            List<Integer> buyUserIds = distributionOrders.stream().map(DistributionOrder::getBuyerUserId).distinct().collect(Collectors.toList());

            //买家用户信息
            List<UserInfo> userInfos = userInfoRepository.gets(buyUserIds);
            Map<Integer, UserInfo> userInfoMap = new HashMap<>();

            if (CollectionUtil.isNotEmpty(userInfos)) {
                userInfoMap = userInfos.stream().collect(Collectors.toMap(UserInfo::getUserId, UserInfo -> UserInfo, (k1, k2) -> k1));
            }

            List<Integer> userLevelIds = userInfos.stream().map(UserInfo::getUserLevelId).distinct().collect(Collectors.toList());

            //买家用户等级信息
            List<UserLevel> userLevelList = userLevelService.gets(userLevelIds);
            Map<Integer, String> userLevelNameMap = new HashMap<>();

            if (CollectionUtil.isNotEmpty(userLevelList)) {
                userLevelNameMap = userLevelList.stream().collect(Collectors.toMap(UserLevel::getUserLevelId, UserLevel::getUserLevelName, (k1, k2) -> k1));
            }

            for (DistributionOrder distributionOrder : distributionOrders) {

                if (CollUtil.isNotEmpty(userInfoMap)) {
                    UserInfo userInfo = userInfoMap.get(distributionOrder.getBuyerUserId());

                    if (userInfo != null) {
                        distributionOrder.setBuyerUserAvatar(userInfo.getUserAvatar());
                        distributionOrder.setBuyerUserName(userInfo.getUserNickname());

                        if (CollUtil.isNotEmpty(userLevelNameMap)) {
                            distributionOrder.setBuyerUserLevelName(userLevelNameMap.get(userInfo.getUserLevelId()));
                        }
                    }
                }
            }

            //收益总金额
            Float uoBuyCommissionTotal = distributionOrderDao.getBuyCommissionTotal(userId, uoLevel, startTime, endTime, true, true);

            if (uoBuyCommissionTotal != null) {
                distributionOrderRes.setUoBuyCommissionTotal(NumberUtil.round(uoBuyCommissionTotal, 2));
            }
        }
        distributionOrderRes.setItems(distributionOrderPage);

        return distributionOrderRes;
    }


    /**
     * 分销结算款项
     *
     * @param order_id 订单编号
     * @return
     */
    @Override
    public boolean settleDistributionUserOrder(String order_id) {
        Date current_time = new Date();
        boolean flag = false;

        QueryWrapper<DistributionOrder> userOrderQueryWrapper = new QueryWrapper<>();
        userOrderQueryWrapper.eq("order_id", order_id).eq("uo_active", false);
        List<DistributionOrder> user_order_rows = find(userOrderQueryWrapper);

        if (CollUtil.isNotEmpty(user_order_rows)) {
            for (DistributionOrder user_order_row : user_order_rows) {

                //需要加入锁
                user_order_row.setUoActive(true);
                user_order_row.setUoReceivetime(current_time.getTime());

                flag = edit(user_order_row);

                //必须更新到记录
                if (flag) {
                    //粉丝产生的佣金记录
                    String ugc_id = String.format("%s-%s-%s", user_order_row.getBuyerUserId(), user_order_row.getUserId(), user_order_row.getUoLevel());

                    DistributionGeneratedCommission user_row = distributionGeneratedCommissionRepository.get(ugc_id);
                    //判断是否存在，不存在则添加

                    if (user_row != null) {
                        //本次产生佣金
                        user_row.setUgcAmount(NumberUtil.add(user_row.getUgcAmount(), user_order_row.getUoBuyCommission(), user_order_row.getUoDirectsellerCommission()));

                        //订单数量
                        user_row.setUgcNum(user_row.getUgcNum() + 1);

                        flag = distributionGeneratedCommissionRepository.edit(user_row);
                    } else {
                        user_row.setUgcId(ugc_id);

                        //本次产生佣金
                        user_row.setUgcAmount(NumberUtil.add(user_order_row.getUoBuyCommission(), user_order_row.getUoDirectsellerCommission()));

                        //订单数量
                        user_row.setUgcNum(1);
                        user_row.setUserId(user_order_row.getBuyerUserId());
                        user_row.setUserParentId(user_order_row.getUserId());
                        user_row.setUgcLevel(user_order_row.getUoLevel());
                        user_row.setUserTime(current_time.getTime());

                        flag = distributionGeneratedCommissionRepository.add(user_row);
                    }


                    //推广员获取佣金
                    DistributionCommission user_commission_row = distributionCommissionRepository.get(user_order_row.getUserId());

                    if (null != user_commission_row) {
                        user_commission_row.setCommissionAmount(NumberUtil.add(user_commission_row.getCommissionAmount(), user_order_row.getUoBuyCommission(), user_order_row.getUoDirectsellerCommission()));

                        if (1 == user_order_row.getUoLevel()) {
                            user_commission_row.setCommissionBuyAmount0(NumberUtil.add(user_commission_row.getCommissionBuyAmount0(), user_order_row.getUoBuyCommission()));
                            user_commission_row.setCommissionDirectsellerAmount0(NumberUtil.add(user_commission_row.getCommissionDirectsellerAmount0(), user_order_row.getUoDirectsellerCommission()));
                        } else if (2 == user_order_row.getUoLevel()) {
                            user_commission_row.setCommissionBuyAmount1(NumberUtil.add(user_commission_row.getCommissionBuyAmount1(), user_order_row.getUoBuyCommission()));
                            user_commission_row.setCommissionDirectsellerAmount1(NumberUtil.add(user_commission_row.getCommissionDirectsellerAmount1(), user_order_row.getUoDirectsellerCommission()));
                        } else if (3 == user_order_row.getUoLevel()) {
                            user_commission_row.setCommissionBuyAmount2(NumberUtil.add(user_commission_row.getCommissionBuyAmount2(), user_order_row.getUoBuyCommission()));
                            user_commission_row.setCommissionDirectsellerAmount2(NumberUtil.add(user_commission_row.getCommissionDirectsellerAmount2(), user_order_row.getUoDirectsellerCommission()));
                        }

                        flag = distributionCommissionRepository.edit(user_commission_row);
                    }
                }
            }

            //修改用户分销订单SKU表信息
            DistributionOrderItem user_order_item_row = new DistributionOrderItem();
            user_order_item_row.setUoiActive(true).setUoiReceivetime(current_time.getTime());

            QueryWrapper<DistributionOrderItem> userOrderItemQueryWrapper = new QueryWrapper<>();
            userOrderItemQueryWrapper.eq("order_id", order_id).eq("uoi_active", false);

            flag = distributionOrderItemRepository.edit(user_order_item_row, userOrderItemQueryWrapper);


            //修改订单分销结算状态
            QueryWrapper<OrderInfo> infoQueryWrapper = new QueryWrapper<>();
            infoQueryWrapper.eq("order_id", order_id).eq("order_fx_is_settlemented", false);

            OrderInfo OrderInfo = new OrderInfo();
            OrderInfo.setOrderFxSettlementTime(current_time);
            OrderInfo.setOrderFxIsSettlemented(true);
            OrderInfo.setOrderId(order_id);

            flag = orderInfoRepository.edit(OrderInfo, infoQueryWrapper);
        }

        return true;
    }


    /**
     * 初始化分销订单信息， 添加三级分销数据
     *
     * @param baseRow  订单基础数据
     * @param itemList 订单商品数据
     */
    public boolean initDistributionUserOrder(DistributionOrderVo baseRow, List<OrderItem> itemList) {
        //不存在分佣
        if (baseRow.getOrderCommissionFee().compareTo(BigDecimal.ZERO) < 0) {
            return false;
        }

        /*
        if (in_array(@baseRow['user_level_product_type'], array(1001, 1002, 1003, 1004)))
        {
            baseRow['order_commission_fee'] = baseRow['order_payment_amount'];
        }

        //判断店铺是否为自营店铺
        Integer store_id = (Integer) baseRow.getStoreId();
        ShopStoreBase store_base_row = shopStoreBaseService.get(store_id);

        if (store_base_row == null) {
            return false;
        }

        //供应商订单不参与分销
        if (2 == store_base_row.getStore_type()) {
            return false;
        }
         */

        Date uoTime = new Date();

        //下单用户
        Integer buyerUserId = baseRow.getUserId();

        //消费奖
        // 分销是否开启
        boolean plantformFxEnable = configBaseService.ifPlantformFx();

        if (plantformFxEnable) {
            Integer current_user_level_id = 1000;  //当前用户最大等级

            //最多三级分销
            int maxLevel = 3;

            int currentLevel = 1;
            Integer currentUserId = buyerUserId;

            while (currentLevel <= maxLevel) {
                UserDistribution distUserRow = userDistributionRepository.get(currentUserId);
                if (distUserRow == null) {
                    break;
                }

                Integer parentId = distUserRow.getUserParentId();
                if (CheckUtil.isEmpty(parentId)) {
                    break;
                }

                UserDistribution parentUserRow = userDistributionRepository.get(parentId);
                if (parentUserRow != null && parentUserRow.getUserActive()) {
                    addDistributionUserOrder(baseRow, itemList, parentId, currentLevel, uoTime);
                }

                currentUserId = parentId;
                currentLevel++;
            }
        }

        return true;
    }

    /**
     * 初始化分销订单信息， 添加三级分销数据
     *
     * @param baseRow  订单基础数据
     * @param itemList 订单商品数据
     * @param userId   佣金获得者用户编号
     * @param uoLevel  分销等级
     * @param uoTime   时间
     */
    public boolean addDistributionUserOrder(DistributionOrderVo baseRow, List<OrderItem> itemList, Integer userId, Integer uoLevel, Date uoTime) {

        /*
        1  : '一级推广消费奖',
        2  : '二级级推广消费奖',
        3  : '三级推广消费奖',
        */

        //一级
        DistributionOrder user_order_row = new DistributionOrder();
        user_order_row.setBuyerUserId(baseRow.getUserId()); // 用户编号
        user_order_row.setStoreId(baseRow.getStoreId()); // 店铺编号
        user_order_row.setUserId(userId); // 用户编号
        user_order_row.setOrderId(baseRow.getOrderId()); // 订单编号

        BigDecimal uo_commission_rate = BigDecimal.ZERO;

        UserInfo userInfo = userInfoRepository.get(userId);

        switch (uoLevel) {
            case 1: //一级推广消费奖
                BigDecimal uo_commission_rate_1 = NumberUtil.div(configBaseService.getDistUserLevelConfig("plantform_fx_cps_rate_1", userInfo.getUserLevelId(), BigDecimal.ZERO), 100);
                user_order_row.setUoBuyCommission(NumberUtil.mul(baseRow.getOrderCommissionFee(), uo_commission_rate_1)); // 推广员佣金
                uo_commission_rate = uo_commission_rate_1;
                break;
            case 2: //二级级推广消费奖
                BigDecimal uo_commission_rate_2 = NumberUtil.div(configBaseService.getDistUserLevelConfig("plantform_fx_cps_rate_2", userInfo.getUserLevelId(), BigDecimal.ZERO), 100);
                user_order_row.setUoBuyCommission(NumberUtil.mul(baseRow.getOrderCommissionFee(), uo_commission_rate_2)); // 推广员佣金
                uo_commission_rate = uo_commission_rate_2;

                break;
            case 3: //三级推广消费奖
                BigDecimal uo_commission_rate_3 = NumberUtil.div(configBaseService.getDistUserLevelConfig("plantform_fx_cps_rate_3", userInfo.getUserLevelId(), BigDecimal.ZERO), 100);
                user_order_row.setUoBuyCommission(NumberUtil.mul(baseRow.getOrderCommissionFee(), uo_commission_rate_3)); // 推广员佣金
                uo_commission_rate = uo_commission_rate_3;

                break;
            default:
                break;
        }

        //服务商获得佣金
        user_order_row.setUoDirectsellerCommission(BigDecimal.ZERO); // 销售员佣金

        user_order_row.setUoLevel(uoLevel); // 等级
        user_order_row.setUoTime(uoTime.getTime()); // 时间
        user_order_row.setUoActive(false); // 是否有效(BOOL):0-未生效;1-有效

        repository.saveOrUpdate(user_order_row);

        addDistributionUserOrderItem(baseRow, itemList, userId, uoLevel, uoTime, uo_commission_rate);

        return true;
    }

    /**
     * 添加订单商品数据
     *
     * @param baseRow  订单基础数据
     * @param itemList 订单商品数据
     * @param userId   佣金获得者用户编号
     * @param uoLevel  分销等级
     * @param uoTime   时间
     */
    public boolean addDistributionUserOrderItem(DistributionOrderVo baseRow, List<OrderItem> itemList, Integer userId, Integer uoLevel, Date uoTime, BigDecimal uoCommissionRate) {
        //循环添加订单商品数据
        for (OrderItem item_row : itemList) {
            DistributionOrderItem distributionOrderItem = new DistributionOrderItem();
            distributionOrderItem.setBuyerUserId(baseRow.getUserId()); // 用户编号
            distributionOrderItem.setStoreId(baseRow.getStoreId()); // 店铺编号
            distributionOrderItem.setUserId(userId); // 用户编号
            distributionOrderItem.setOrderId(baseRow.getOrderId()); // 订单编号
            distributionOrderItem.setProductId(item_row.getProductId()); //
            distributionOrderItem.setItemId(item_row.getItemId()); //

            //判断uo_level,决定佣金类型

            //只判断销售奖，其它按照default处理
            switch (uoLevel) {
                case 1: //一级推广消费奖
                    distributionOrderItem.setUoiBuyCommission(NumberUtil.mul(item_row.getOrderItemCommissionFee(), uoCommissionRate));
                    break;
                case 2: //二级级推广消费奖
                    distributionOrderItem.setUoiBuyCommission(NumberUtil.mul(item_row.getOrderItemCommissionFee(), uoCommissionRate));
                    break;
                default:
                    distributionOrderItem.setUoiBuyCommission(NumberUtil.mul(item_row.getOrderItemCommissionFee(), uoCommissionRate));
                    break;
            }

            //distributionOrderItem["uoi_directseller_commission"] = 0; // 销售员佣金
            //distributionOrderItem["uoi_distributor_commission"]  = 0; // 分销商收益-本店销售获取差价
            distributionOrderItem.setUoiLevel(uoLevel); // 等级
            distributionOrderItem.setUoiTime(uoTime.getTime()); // 时间
            distributionOrderItem.setUoiActive(false); // 是否有效(BOOL):0-未生效;1-有效

            distributionOrderItemRepository.add(distributionOrderItem);
        }

        return true;
    }

    @Override
    public IPage<DistributionOrder> getList(DistributionOrderListReq distributionOrderListReq) {
        IPage<DistributionOrder> lists = lists(distributionOrderListReq);
        if (lists != null && CollectionUtil.isNotEmpty(lists.getRecords())) {
            List<DistributionOrder> distributionOrders = lists.getRecords();
            List<Integer> userIds = CommonUtil.column(distributionOrders, DistributionOrder::getUserId);
            List<Integer> buyUserIds = CommonUtil.column(distributionOrders, DistributionOrder::getBuyerUserId);
            //推广员昵称
            Map<Integer, String> userNickNameMap = getUserNickname(userIds);
            //买家昵称
            Map<Integer, String> buyUserNicknameMap = getUserNickname(buyUserIds);
            for (DistributionOrder distributionOrder : distributionOrders) {

                if (CollUtil.isNotEmpty(userNickNameMap)) {
                    distributionOrder.setUserNickname(userNickNameMap.get(distributionOrder.getUserId()));
                }

                if (CollUtil.isNotEmpty(buyUserNicknameMap)) {
                    distributionOrder.setBuyerUserName(buyUserNicknameMap.get(distributionOrder.getBuyerUserId()));
                }
            }
        }

        return lists;
    }

    private Map<Integer, String> getUserNickname(List<Integer> userIds) {
        List<UserInfo> userInfos = userInfoRepository.gets(userIds);
        Map<Integer, String> userMap = new HashMap<>();

        if (CollectionUtil.isNotEmpty(userInfos)) {
            userMap = userInfos.stream().collect(Collectors.toMap(UserInfo::getUserId, UserInfo::getUserNickname, (k1, k2) -> k1));
        }

        return userMap;
    }
}
